package cn.bellychang.ood.payroll;

import cn.bellychang.ood.payroll.affiliation.NonAffiliation;
import cn.bellychang.ood.payroll.affiliation.UnionAffiliation;
import cn.bellychang.ood.payroll.classification.CommissionedClassification;
import cn.bellychang.ood.payroll.classification.HourlyClassification;
import cn.bellychang.ood.payroll.classification.SalariedClassification;
import cn.bellychang.ood.payroll.domain.*;
import cn.bellychang.ood.payroll.paymethod.BankMethod;
import cn.bellychang.ood.payroll.paymethod.HoldMethod;
import cn.bellychang.ood.payroll.paymethod.MailMethod;
import cn.bellychang.ood.payroll.schedule.BiweeklySchedule;
import cn.bellychang.ood.payroll.schedule.MonthlySchedule;
import cn.bellychang.ood.payroll.schedule.WeeklySchedule;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Maps;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author ChangLiang
 * @date 2020/5/19
 */
@Slf4j
public class PayrollService {

    public List<Employee> getAllEmployees(){
        List<Employee> employees = new ArrayList<>();
        employees.add(this.addHourlyEmployee("changliang", "hangzhou",
                Money.of(CurrencyUnit.of("CNY"), 200),
                Maps.newHashMap(new Date(), TimeCard.builder().date(new Date()).hours(9).build())));
        employees.add(this.addSalariedEmployee("changliang2", "hangzhou2",
                Money.of(CurrencyUnit.of("CNY"), 7000),
                Maps.newHashMap(new Date(), ServiceCharge.builder().date(new Date()).amount(Money.of(CurrencyUnit.of("CNY"), 3000)).build())
        ));
        employees.add(this.addCommissionEmployee("changliang3", "hangzhou3",
                Money.of(CurrencyUnit.of("CNY"), 2000),
                Money.of(CurrencyUnit.of("CNY"), 500),
                Maps.newHashMap(new Date(), SalesReceipt.builder().date(new Date()).amount(10).build())));
        return employees;
    }

    /**
     * 保存已发放工资条
     * @param paycheck
     */
    public void savePayCheck(Paycheck paycheck) {
        log.info("payrollService save paycheck: {}", paycheck);
    }

    /**
     * 每天工作记录保存到Map中
     * @param name
     * @param address
     * @param hourlyRate
     * @param map
     * @return
     */
    public Employee addHourlyEmployee(String name, String address, Money hourlyRate, Map<Date, TimeCard> map){
        Employee employee = Employee.builder()
                .id(1L)
                .name(name)
                .address(address)
                .paymentClassification(HourlyClassification.builder().rate(hourlyRate).timeCards(map).build())
                .paymentMethod(new BankMethod())
                .paymentSchedule(new WeeklySchedule())
                .affiliation(new NonAffiliation())
                .build();
        return employee;
    }

    /**
     * 每一条扣款记录保存到Map中
     * @param name
     * @param address
     * @param salary
     * @param map
     * @return
     */
    public Employee addSalariedEmployee(String name, String address, Money salary, Map<Date, ServiceCharge> map){
        Employee employee = Employee.builder()
                .id(2L)
                .name(name)
                .address(address)
                .paymentClassification(SalariedClassification.builder().salary(salary).build())
                .paymentMethod(new HoldMethod())
                .paymentSchedule(new MonthlySchedule())
                .affiliation(UnionAffiliation.builder().deductionMap(map).build())
                .build();
        return employee;
    }

    /**
     * 有销售记录保存到map中
     * @param name
     * @param address
     * @param salary
     * @param rate
     * @param map
     * @return
     */
    public Employee addCommissionEmployee(String name, String address, Money salary, Money rate, Map<Date, SalesReceipt> map){
        Employee employee = Employee.builder()
                .id(3L)
                .name(name)
                .address(address)
                .paymentClassification(CommissionedClassification.builder().salary(salary).rate(rate).receiptMap(map).build())
                .paymentMethod(new MailMethod())
                .paymentSchedule(new BiweeklySchedule())
                .affiliation(new NonAffiliation())
                .build();
        return employee;
    }
}
